{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# type()\n",
    "我们说class的定义是运行时动态创建的，而创建class的方法就是使用type()函数。\n",
    "\n",
    "type()函数既可以返回一个对象的类型，又可以创建出新的类型，比如，我们可以通过type()函数创建出Hello类，而无需通过class Hello(object)...的定义："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello, world.\n"
     ]
    }
   ],
   "source": [
    " def fn(self, name = 'world'): # 先定义函数\n",
    "     print('Hello, %s.' % name)\n",
    "\n",
    "Hello = type('Hello', (object,), dict(hello = fn)) # 创建Hello class\n",
    "h = Hello()\n",
    "h.hello()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'type'>\n"
     ]
    }
   ],
   "source": [
    "print(type(Hello))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class '__main__.Hello'>\n"
     ]
    }
   ],
   "source": [
    "print(type(h))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "要创建一个class对象，type()函数依次传入3个参数：\n",
    "\n",
    "- class的名称；\n",
    "- 继承的父类集合，注意Python支持多重继承，如果只有一个父类，别忘了tuple的单元素写法；\n",
    "- class的方法名称与函数绑定，这里我们把函数fn绑定到方法名hello上。\n",
    "\n",
    "通过type()函数创建的类和直接写class是完全一样的，因为Python解释器遇到class定义时，仅仅是扫描一下class定义的语法，然后调用type()函数创建出class。\n",
    "\n",
    "正常情况下，我们都用class Xxx...来定义类，但是，type()函数也允许我们动态创建出类来，也就是说，动态语言本身支持运行期动态创建类，这和静态语言有非常大的不同，要在静态语言运行期创建类，必须构造源代码字符串再调用编译器，或者借助一些工具生成字节码实现，本质上都是动态编译，会非常复杂。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# metaclass(元类）\n",
    "要控制类的创建行为，还可以使用metaclass。\n",
    "\n",
    "metaclass，直译为元类，简单的解释就是：\n",
    "\n",
    "当我们定义了类以后，就可以根据这个类创建出实例，所以：先定义类，然后创建实例。\n",
    "\n",
    "但是如果我们想创建出类呢？那就必须根据metaclass创建出类，所以：先定义metaclass，然后创建类。\n",
    "\n",
    "连接起来就是：先定义metaclass，就可以创建类，最后创建实例。\n",
    "\n",
    "所以，metaclass允许你创建类或者修改类。换句话说，你可以把类看成是metaclass创建出来的“实例”。\n",
    "\n",
    "......"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
